package com.hujie.sqlqueryes.controller;

import com.hujie.sqlqueryes.dto.DslResultDTO;
import com.hujie.sqlqueryes.dto.R;
import com.hujie.sqlqueryes.service.ElasticsearchService;
import com.hujie.sqlqueryes.service.UserContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api/es")
@CrossOrigin(origins = {"http://localhost:5173", "http://localhost:3000", "http://localhost:3001", 
                       "http://localhost:3002", "http://localhost:3003", "http://localhost:3004"}, 
           allowCredentials = "true")
public class ElasticsearchController {

    @Autowired
    private ElasticsearchService elasticsearchService;

    /**
     * 获取用户ID，优先从请求头获取，如果没有则从会话中获取或创建一个新的
     */
    private String getUserId(HttpServletRequest request) {
        // 首先尝试从请求头获取userId
        String userId = request.getHeader("X-User-Id");
        if (userId != null && !userId.isEmpty()) {
            return userId;
        }
        
        // 如果请求头中没有userId，则从会话中获取或创建
        HttpSession session = request.getSession();
        userId = (String) session.getAttribute("userId");
        if (userId == null) {
            userId = UUID.randomUUID().toString();
            session.setAttribute("userId", userId);
        }
        return userId;
    }

    @PostMapping("/connect")
    public R<String> connect(HttpServletRequest request, @RequestBody Map<String, String> connectionInfo) {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            String host = connectionInfo.get("host");
            int port = Integer.parseInt(connectionInfo.getOrDefault("port", "9200"));
            
            boolean connected = elasticsearchService.connect(userId, host, port);
            if (connected) {
                return R.success(userId, "连接成功");
            } else {
                return R.error("连接失败");
            }
        } catch (Exception e) {
            return R.error("连接失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }
    
    // 添加检查Elasticsearch连接状态的端点
    @GetMapping("/connection/status")
    public R<Boolean> checkConnectionStatus(HttpServletRequest request) {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (elasticsearchService.isCurrentConnected()) {
                // 尝试获取索引列表来检查连接
                elasticsearchService.getAllIndices();
                return R.success(true, "Elasticsearch连接正常");
            } else {
                return R.success(false, "用户未连接到Elasticsearch");
            }
        } catch (Exception e) {
            return R.error("Elasticsearch连接异常: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    @GetMapping("/indices")
    public R<List<String>> getIndices(HttpServletRequest request) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            List<String> indices = elasticsearchService.getAllIndices();
            return R.success(indices);
        } catch (Exception e) {
            return R.error("获取索引列表失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    @PostMapping("/indices")
    public R<String> createIndex(HttpServletRequest request, @RequestBody Map<String, String> indexInfo) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            String indexName = indexInfo.get("indexName");
            String mapping = indexInfo.get("mapping");
            
            boolean result;
            if (mapping != null && !mapping.isEmpty()) {
                result = elasticsearchService.createIndexWithMapping(indexName, mapping);
            } else {
                result = elasticsearchService.createIndex(indexName);
            }
            
            if (result) {
                return R.success("索引创建成功");
            } else {
                return R.error("索引创建失败，可能索引已存在");
            }
        } catch (Exception e) {
            return R.error("创建索引时出错: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    // 添加删除索引的接口
    @DeleteMapping("/indices/{indexName}")
    public R<String> deleteIndex(HttpServletRequest request, @PathVariable String indexName) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            boolean result = elasticsearchService.deleteIndex(indexName);
            if (result) {
                return R.success("索引删除成功");
            } else {
                return R.error("索引删除失败");
            }
        } catch (Exception e) {
            return R.error("删除索引时出错: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    // 添加获取索引映射信息的接口
    @GetMapping("/indices/{indexName}/mapping")
    public R<Map<String, Object>> getIndexMapping(HttpServletRequest request, @PathVariable String indexName) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            Map<String, Object> mapping = elasticsearchService.getIndexMapping(indexName);
            return R.success(mapping);
        } catch (Exception e) {
            return R.error("获取索引映射信息失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    @PostMapping("/indices/{indexName}/mapping")
    public R<String> updateIndexMapping(HttpServletRequest request, @PathVariable String indexName, @RequestBody Map<String, Object> mappingInfo) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            boolean result = elasticsearchService.updateIndexMapping(indexName, mappingInfo);
            if (result) {
                return R.success("索引映射更新成功");
            } else {
                return R.error("索引映射更新失败");
            }
        } catch (Exception e) {
            return R.error("更新索引映射时出错: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    // 添加获取索引设置信息的接口
    @GetMapping("/indices/{indexName}/settings")
    public R<Map<String, Object>> getIndexSettings(HttpServletRequest request, @PathVariable String indexName) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            Map<String, Object> settings = elasticsearchService.getIndexSettings(indexName);
            return R.success(settings);
        } catch (Exception e) {
            return R.error("获取索引设置信息失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    @GetMapping("/indices/{indexName}/data")
    public R<Map<String, Object>> getIndexData(
            HttpServletRequest request,
            @PathVariable String indexName,
            @RequestParam(defaultValue = "0") int from,
            @RequestParam(defaultValue = "10") int size) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            Map<String, Object> data = elasticsearchService.getIndexData(indexName, from, size);
            return R.success(data);
        } catch (Exception e) {
            return R.error("获取索引数据失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    @PostMapping("/sql")
    public R<Map<String, Object>> executeSql(HttpServletRequest request, @RequestBody Map<String, String> sqlInfo) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            String sql = sqlInfo.get("sql");
            Map<String, Object> result = elasticsearchService.executeSqlQuery(sql);
            return R.success(result);
        } catch (Exception e) {
            return R.error("执行SQL失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }

    @PostMapping("/query")
    public R<Map<String, Object>> executeQuery(HttpServletRequest request, @RequestBody Map<String, String> queryInfo) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            String sql = queryInfo.get("sql");
            Map<String, Object> result = elasticsearchService.executeQuery(sql);
            return R.success(result);
        } catch (Exception e) {
            return R.error("执行查询失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }
    
    @PostMapping("/dsl")
    public R<Map<String, Object>> executeDsl(HttpServletRequest request, @RequestBody Map<String, String> dslInfo) throws IOException {
        String userId = getUserId(request);
        UserContext.setUserId(userId);
        try {
            // 检查用户是否已连接
            if (!elasticsearchService.isCurrentConnected()) {
                return R.error("用户未连接到Elasticsearch");
            }
            
            String dsl = dslInfo.get("dsl");
            Map<String, Object> result = elasticsearchService.executeDslQuery(dsl);
            return R.success(result);
        } catch (Exception e) {
            return R.error("执行DSL失败: " + e.getMessage());
        } finally {
            // 不再在这里清理UserContext，由拦截器统一处理
        }
    }
}